home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / macros / texinfo / info / signals.c < prev    next >
C/C++ Source or Header  |  1994-01-28  |  5KB  |  178 lines

  1. /* signals.c -- Install and maintain Info signal handlers. */
  2.  
  3. /* This file is part of GNU Info, a program for reading online documentation
  4.    stored in Info format.
  5.  
  6.    Copyright (C) 1993 Free Software Foundation, Inc.
  7.  
  8.    This program is free software; you can redistribute it and/or modify
  9.    it under the terms of the GNU General Public License as published by
  10.    the Free Software Foundation; either version 2, or (at your option)
  11.    any later version.
  12.  
  13.    This program is distributed in the hope that it will be useful,
  14.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.    GNU General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with this program; if not, write to the Free Software
  20.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22.    Written by Brian Fox (bfox@ai.mit.edu). */
  23.  
  24. #include "info.h"
  25. #include "signals.h"
  26.  
  27. /* **************************************************************** */
  28. /*                                    */
  29. /*        Pretending That We Have POSIX Signals            */
  30. /*                                    */
  31. /* **************************************************************** */
  32.  
  33. #if !defined (_POSIX_VERSION)
  34. /* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */
  35. static void
  36. sigprocmask (operation, newset, oldset)
  37.      int operation, *newset, *oldset;
  38. {
  39.   switch (operation)
  40.     {
  41.     case SIG_UNBLOCK:
  42. #if defined (HAVE_SIGSETMASK)
  43.       sigsetmask (sigblock (0) & ~(*newset));
  44. #endif /* HAVE_SIGSETMASK */
  45.       break;
  46.  
  47.     case SIG_BLOCK:
  48.       *oldset = sigblock (*newset);
  49.       break;
  50.  
  51.     case SIG_SETMASK:
  52. #if defined (HAVE_SIGSETMASK)
  53.       sigsetmask (*newset);
  54. #endif /* HAVE_SIGSETMASK */
  55.       break;
  56.  
  57.     default:
  58.       abort ();
  59.     }
  60. }
  61. #endif /* !_POSIX_VERSION */
  62.  
  63. /* **************************************************************** */
  64. /*                                    */
  65. /*            Signal Handling for Info                */
  66. /*                                    */
  67. /* **************************************************************** */
  68.  
  69. typedef void SigHandlerType;
  70. typedef SigHandlerType SigHandler ();
  71.  
  72. static SigHandlerType info_signal_handler ();
  73. static SigHandler *old_TSTP, *old_TTOU, *old_TTIN;
  74. static SigHandler *old_WINCH, *old_INT;
  75.  
  76. void
  77. initialize_info_signal_handler ()
  78. {
  79. #if defined (SIGTSTP)
  80.   old_TSTP = (SigHandler *) signal (SIGTSTP, info_signal_handler);
  81.   old_TTOU = (SigHandler *) signal (SIGTTOU, info_signal_handler);
  82.   old_TTIN = (SigHandler *) signal (SIGTTIN, info_signal_handler);
  83. #endif /* SIGTSTP */
  84.  
  85. #if defined (SIGWINCH)
  86.   old_WINCH = (SigHandler *) signal (SIGWINCH, info_signal_handler);
  87. #endif
  88.  
  89. #if defined (SIGINT)
  90.   old_INT = (SigHandler *) signal (SIGINT, info_signal_handler);
  91. #endif
  92. }
  93.  
  94. static void
  95. redisplay_after_signal ()
  96. {
  97.   terminal_clear_screen ();
  98.   display_clear_display (the_display);
  99.   window_mark_chain (windows, W_UpdateWindow);
  100.   display_update_display (windows);
  101.   display_cursor_at_point (active_window);
  102.   fflush (stdout);
  103. }
  104.  
  105. static SigHandlerType
  106. info_signal_handler (sig)
  107.      int sig;
  108. {
  109.   SigHandler **old_signal_handler;
  110.  
  111.   switch (sig)
  112.     {
  113. #if defined (SIGTSTP)
  114.     case SIGTSTP:
  115.     case SIGTTOU:
  116.     case SIGTTIN:
  117. #endif
  118. #if defined (SIGINT)
  119.     case SIGINT:
  120. #endif
  121.       {
  122. #if defined (SIGTSTP)
  123.     if (sig == SIGTSTP)
  124.       old_signal_handler = &old_TSTP;
  125.     if (sig == SIGTTOU)
  126.       old_signal_handler = &old_TTOU;
  127.     if (sig == SIGTTIN)
  128.       old_signal_handler = &old_TTIN;
  129. #endif /* SIGTSTP */
  130.     if (sig == SIGINT)
  131.       old_signal_handler = &old_INT;
  132.  
  133.     /* For stop signals, restore the terminal IO, leave the cursor
  134.        at the bottom of the window, and stop us. */
  135.     terminal_goto_xy (0, screenheight - 1);
  136.     terminal_clear_to_eol ();
  137.     fflush (stdout);
  138.     terminal_unprep_terminal ();
  139.     signal (sig, *old_signal_handler);
  140.      UNBLOCK_SIGNAL (sig);
  141.     kill (getpid (), sig);
  142.  
  143.     /* The program is returning now.  Restore our signal handler,
  144.        turn on terminal handling, redraw the screen, and place the
  145.        cursor where it belongs. */
  146.     terminal_prep_terminal ();
  147.     *old_signal_handler = (SigHandler *) signal (sig, info_signal_handler);
  148.     redisplay_after_signal ();
  149.     fflush (stdout);
  150.       }
  151.       break;
  152.  
  153. #if defined (SIGWINCH)
  154.     case SIGWINCH:
  155.       {
  156.     /* Turn off terminal IO, tell our parent that the window has changed,
  157.        then reinitialize the terminal and rebuild our windows. */
  158.     old_signal_handler = &old_WINCH;
  159.     terminal_goto_xy (0, 0);
  160.     fflush (stdout);
  161.     terminal_unprep_terminal ();
  162.     signal (sig, *old_signal_handler);
  163.      UNBLOCK_SIGNAL (sig);
  164.     kill (getpid (), sig);
  165.  
  166.     /* After our old signal handler returns... */
  167.     terminal_get_screen_size ();
  168.     terminal_prep_terminal ();
  169.     display_initialize_display (screenwidth, screenheight);
  170.     window_new_screen_size (screenwidth, screenheight, (VFunction *)NULL);
  171.     *old_signal_handler = (SigHandler *) signal (sig, info_signal_handler);
  172.     redisplay_after_signal ();
  173.       }
  174.       break;
  175. #endif /* SIGWINCH */
  176.     }
  177. }
  178.